package chaoyue.study.lock;

import chaoyue.study.ThreadUtils;

/**
 * 死锁
 * synchronized 嵌套使用相当于加多把锁，会产生死锁现象
 * 可以看到此时就发生来死锁，主线程永远都没有结束
 * 产生死锁的四个必要条件
 * 1. 互斥（Mutual Exclusion）：资源不共享
 * 2. 请求与保持（Hold and Wait）：等待过程中不释放资源 一直持有
 * 3. 不可剥夺（No Preemption）：不得强行剥夺其他线程占有的资源
 * 4. 循环等待（Circular Wait）：都在等待对方释放资源
 * 破坏以上任何一个条件，都可以打破死锁
 */
public class DeadLockTest {
    public static void main(String[] args) {
        // 模拟两个临界资源
        Object o1 = new Object();
        Object o2 = new Object();
        // 先获取o1的锁，然后再去获取o2的锁
        new MyDeadLock(o1, o2).start();
        // 先获取o2的锁，然后再去获取o1的锁
        new MyDeadLock(o2, o1).start();
    }

    private static class MyDeadLock extends Thread {
        private final Object a;
        private final Object b;

        public MyDeadLock(Object a, Object b) {
            this.a = a;
            this.b = b;
        }

        public void run() {
            synchronized (a) {
                ThreadUtils.sleep();
                synchronized (b) {
                    // 获取到两个资源的锁之后，开始进行业务逻辑处理
                    System.out.println(Thread.currentThread().getName() + "run()...");
                }
            }
        }
    }
}

